#include "PositionRanker.h"
#include "../WellSizedVector2.h"
#include "../PositionVector.h"
#include "MinPositionMatrix.h"
#include <vector>

using namespace std;


vector<double> PositionRanker::getRank(vector<WellSizedVector2> wsvVector) {
	uint numIds = wsvVector[0].getVectorSize();
	uint numPalavras = wsvVector.size();
	vector<double> ranks(numIds);
	vector<PositionVector *> posVectors;
	vector<uint> indexVector(numPalavras);
	
	
	
	struct minStruct minValueAndPos;
	
	for (uint i = 0; i < numIds; i++) {
		for (uint j = 0; j < numPalavras; j++) {
			indexVector[j] = 0;
			posVectors.push_back(wsvVector[j].getSpecificPositionVector(i));
			nextPositions.push_back( posVectors[j]->getFirstOccurrence() );
//			cout << "posVectors[j].getFirstOccurrence() " << posVectors[j].getFirstOccurrence() << endl;
		}
		
		MinPositionMatrix mpm(numPalavras, nextPositions);
		
		while (hasNewPositions()) {
			minValueAndPos = getMin(posVectors, indexVector);
//			cout << "minValueAndPos.minValue: " << minValueAndPos.minValue << endl;
			mpm.updateWithPosition(minValueAndPos.minValue, minValueAndPos.pos);
//			mpm.showMatrix();
//			cout << endl;
		}
		
		ranks[i] = double(numPalavras) / mpm.getMin();
//		cout << endl << endl << ranks[i] << endl << endl;
		nextPositions.clear();
		posVectors.clear();
	}
	
	return ranks;
}


bool PositionRanker::hasNewPositions() {
	for (uint i = 0; i < numPalavras; i++)
		if (nextPositions[i] != -1)
			return true;
	return false;
}


struct minStruct PositionRanker::getMin(vector<PositionVector *> & posVectors, vector<uint> & indexVector ) {
	struct minStruct minAndPos;
	uint min = -1;
	uint pos;
	//Acha o minimo
	for (uint i = 0; i < numPalavras; i++) {
//		cout << "nextPositions[i]: " << nextPositions[i] << endl;
		if (min > nextPositions[i]) {
			min = nextPositions[i];
			pos = i;
		}
	}
	
	//retira o minimo e atualiza nextPositions
	
//	cout << "pos: " << pos << endl;
//	cout << "indexVector[pos]: " << indexVector[pos] << endl;
//	cout << posVectors[pos].showPositions() << endl;
	uint offset = posVectors[pos]->getOffsetAt(indexVector[pos]);
	indexVector[pos] = indexVector[pos] + 1;
//	cout << "offset: " << offset << endl;
	if (offset == -1)
		nextPositions[pos] = -1;
	else
		nextPositions[pos] = nextPositions[pos] + offset;
	
//	cout << "min: " << min << endl << endl;;
	
	minAndPos.minValue = min;
	minAndPos.pos = pos;
	return minAndPos;
}
